/*global $, jQuery*/
/*
 *{titles}  : 轮播插件
 *{author}  : daFei
 *{version} : v.0.1
**/

(function($) {
  'use strict';
  $.fn.slide = function(options) {
    var
      defaults = {
        ms: 5000,
        dn: 600,
        type: 'slide',
        isAuto: true,
        isLoop: true,
        isMarker: true,
        isController: true,
		callbackCurIndex: null
      },
      settings = $.extend(defaults, options),
      self = this,
      dom = {
        target: self.find('.slide-wrap'),
        element: self.find('.slide-element'),
        items: self.find('.slide-element').children('li'),
        markerWrap: null,
        markerItem: null,
        controllerWrap: null,
        controllerPrev: null,
        controllerNext: null,
        cloneFirstNode: null,
        cloneLastNode: null
      },
      params = {
        width: dom.items.width(),
        count: dom.items.length,
        curSlide: 1,
        curIndex: 0,
        nextSlide: 0,
        nextIndex: 0,
        timer: null,
        isAnimated: false
      },
      dirs = {
        prev: 'prev',
        next: 'next'
      },
      init,
      private_marker,
      private_controller,
      private_slide,
      private_stop,
      private_next,
      private_go,
	  private_cbCurIndex;

    init = function() {
      if (params.count > 1) {

        if (settings.isMarker) {
          private_marker();
        }
        if (settings.isController) {
          private_controller();
        }
        if (settings.type === 'slide') {
          private_slide();
        }
        if (settings.isAuto) {
          private_stop();
        }
      } else {
        settings.isAuto = false;
      }

      dom.items.eq(params.curIndex).show();

      if (settings.type === 'slide' && settings.isLoop && params.count > 1) {
        params.curSlide = 2;
        params.curIndex = 1;
      }

      if (params.count > 1 && settings.isLoop) {
        dom.controllerWrap.hide();
      }

      if (settings.isAuto) {
        params.timer = setInterval(function() {
          private_go(dirs.next, null);
        }, settings.ms);
      }
    };

    private_marker = function() {
      var markerNum = params.count - Number(dom.target.width() / dom.items.width());

      dom.markerWrap = $('<ol class="slide-marker"></ol>');

      $.each(dom.items, function(key) {
        if (Number(key) <= markerNum) {
          var
            markerdigital = Number(key) + 1,
            goToNextSlide = Number(key) + 1,
            marker;

          if (settings.type === 'slide' && settings.isLoop) {
              goToNextSlide = key + 2;
          }

          marker = $('<li><a href="javascript:void(0);">' + markerdigital + '</a></li>');

          if (markerdigital === params.curSlide) {
            marker.addClass('active');
          }

          marker.on('click', 'a', function() {
            if (!params.isAnimated && params.curSlide !== goToNextSlide) {
              private_go(null, goToNextSlide);
            }
          });

          marker.appendTo(dom.markerWrap);
        }
      });

      dom.markerWrap.appendTo(self);
      dom.markerItem = dom.markerWrap.find('li');
      dom.markerWrap.css({
        'margin-left': -dom.markerWrap.width() / 2
      });
    };

    private_controller = function() {
      var markerNum = params.count - Number(dom.target.width() / dom.items.width());

      dom.controllerWrap = $('<div class="slide-controller"></div>');
      dom.controllerPrev = $('<span class="prev" data-direction="' + dirs.prev + '"><i class="icon-font icon-arrow-prev"></i></span>');
      dom.controllerNext = $('<span class="next" data-direction="' + dirs.next + '"><i class="icon-font icon-arrow-next"></i></span>');

      dom.controllerWrap.on('click', 'span', function() {
        var dir = $(this).attr('data-direction');

        if (!params.isAnimated) {
          if (dir === dirs.prev) {
            private_go(dirs.prev, null);
          }
          if (dir === dirs.next) {
            if (settings.isLoop) {
              private_go(dirs.next, null);
            } else if (params.nextIndex < markerNum) {
              private_go(dirs.next, null);
            }
          }
        }
      });

      dom.controllerPrev.appendTo(dom.controllerWrap);
      dom.controllerNext.appendTo(dom.controllerWrap);
      dom.controllerWrap.appendTo(self);
    };

    private_slide = function() {
      if (settings.isLoop) {
        dom.cloneFirstNode = dom.items.eq(0).clone();
        dom.cloneLastNode = dom.items.eq(params.count - 1).clone();

        dom.cloneFirstNode.attr({
          'data-clone': 'last'
        }).appendTo(dom.element).show();
        dom.cloneLastNode.attr({
          'data-clone': 'first'
        }).prependTo(dom.element).show();

        dom.items = dom.element.children('li');
        params.count = dom.items.length;

        dom.element.css({
          'left': -params.width * params.curSlide,
          'width': params.width * params.count
        });
      } else {
        dom.controllerNext.addClass('active');
        dom.element.css({
          'left': -params.width * params.curIndex,
          'width': params.width * params.count
        });
      }
    };

    private_stop = function() {
      self.hover(function() {
        clearInterval(params.timer);

        if (params.count > 1 && settings.isLoop) {
          dom.controllerWrap.show();
        }
      }, function() {
        params.timer = setInterval(function() {
          private_go(dirs.next, null);
        }, settings.ms);

        if (params.count > 1 && settings.isLoop) {
        	dom.controllerWrap.hide();
        }
      });
    };

    private_next = function(dir) {
      var markerNum = params.count - Number(dom.target.width() / dom.items.width());

      if (dir === dirs.prev) {
        if (dom.items.eq(params.curIndex).prev().length) {
          if (dom.items.eq(params.nextIndex).prev().length) {
            dom.controllerPrev.addClass('active');
            dom.controllerNext.addClass('active'); 
          }

          params.nextSlide = params.curSlide - 1;
          params.nextIndex = params.curIndex - 1;

          if (!dom.items.eq(params.nextIndex).prev().length) {
            dom.controllerPrev.removeClass('active');
          }
        } else if (settings.isLoop) {
          params.nextSlide = params.count;
          params.nextIndex = params.count - 1;
        }
      }

      if (dir === dirs.next) {
        if (dom.items.eq(params.curIndex).next().length) {
          if (params.nextIndex < markerNum) {
            dom.controllerPrev.addClass('active');
            dom.controllerNext.addClass('active'); 
          }

          params.nextSlide = params.curSlide + 1;
          params.nextIndex = params.curIndex + 1;

          if (params.nextIndex >= markerNum) {
            dom.controllerNext.removeClass('active');
          }
        } else if (settings.isLoop) {
          params.nextSlide = 1;
          params.nextIndex = 0;
        }
      }
    };

    private_go = function(dir, pos) {
      if (!params.isAnimated) {
        params.isAnimated = true;

        if (pos) {
          params.nextSlide = pos;
          params.nextIndex = pos - 1;
        } else {
          private_next(dir);
        }

        if (settings.type === 'fade') {
          if (settings.isMarker) {
            dom.markerItem.removeClass('active');
            dom.markerItem.eq(params.nextIndex).addClass('active');
          }

          dom.items.eq(params.curIndex).fadeOut(settings.dn);
          dom.items.eq(params.nextIndex).fadeIn(settings.dn, function() {
            params.isAnimated = false;
            params.curSlide = params.nextSlide;
            params.curIndex = params.nextIndex;
			private_cbCurIndex();
          });
        }

        if (settings.type === 'slide') {
          if (settings.isMarker) {
            var markerIndex;

            if (settings.isLoop) {
              markerIndex = params.nextIndex - 1;

              if (markerIndex === params.count - 2) {
                markerIndex = 0;
              } else if (markerIndex === -1) {
                markerIndex = params.count - 3;
              }
            } else {
              markerIndex = params.nextIndex;
            }
            
            dom.markerItem.removeClass('active');
            dom.markerItem.eq(markerIndex).addClass('active');
          }
          dom.element.animate({
            'left': -params.nextIndex * params.width
          }, settings.dn, function() {
            params.isAnimated = false;
            params.curSlide = params.nextSlide;
            params.curIndex = params.nextIndex;

            if (settings.isLoop) {
              if (dom.items.eq(params.curIndex).attr('data-clone') === 'last') {
                dom.element.css({
                  'left': -params.width
                });
                params.curSlide = 2;
                params.curIndex = 1;
              }

              if (dom.items.eq(params.curIndex).attr('data-clone') === 'first') {
                dom.element.css({
                  'left': -params.width * (params.count - 2)
                });
                params.curSlide = params.count - 1;
                params.curIndex = params.count - 2;
              }
            }
			private_cbCurIndex();
          });
        }
      }
    };
	private_cbCurIndex = function(){
		if(settings.callbackCurIndex && $.isFunction(settings.callbackCurIndex)){
			settings.callbackCurIndex(params.curIndex);
		}
	};

    init();
  };
}(jQuery));